<?php
abstract class Croese_Google_Chart_Abstract
{

	protected $_chartUrl = 'http://chart.apis.google.com/chart?';
	protected $_parameters = array();
	protected $_separator = '&amp;';
	
	protected $_data = array();
	protected $_title = 'No Title';
	protected $_cacheDir = 'C:\Program Files\wamp\www\dev.jaconferentie.nl\public\cache';
	
	public function __construct($width, $height, $chartData, Croese_Google_Chart_Encoding $encoding, $charType)
	{
		$this->setChartSize($width, $height);
		
		$this->setChartData($chartData, $encoding);
		$this->_data = $chartData;
		
		$this->setChartType($charType);
	}
	
	public function getUrl()
	{
		/*
		if (file_exists($this->_cacheDir . '/' . $this->generateCacheName($this->_data, $this->_title)))
		{
			return '/cache/' . $this->generateCacheName($this->_data, $this->_title);	
		}
		else
		{
			$url = $this->_chartUrl . implode($this->_separator, $this->_parameters);	
			
			$cacheUrl = $this->_chartUrl . implode('&', $this->_parameters);
			
			$this->saveToCache($cacheUrl, $this->_title);
			return $url;
		}
		*/
		$url = $this->_chartUrl . implode($this->_separator, $this->_parameters);
		return $url;
		
		
	}
	
	private function generateCacheName()
	{
		return urlencode(strtolower($this->_title)) . '.' . sha1(serialize($this)) . '.png';
	}
	
	public function saveToCache($url, $title)
	{
		file_put_contents($this->_cacheDir . '/' . $this->generateCacheName($this->_data, $title), file_get_contents($url));	
	}
	
	public function getImage()
	{
		$url = $this->getUrl();
		// @todo later nog de alt en title e.d. zetten
		return '<img src="' . $url . '" alt="' . $this->_title .'" />';
	}
	
	private function addParameter($type, $value)
	{
		$this->_parameters[$type] = $value; 	
	}
	
	public function setChartSize($width, $height)
	{
		// @todo nog een controle of we niet over de maximale grootte heen gaan
		/**
		 * chs=<width in pixels>x<height in pixels>
		 * 
		 * For example, chs=300x200 generates a chart 300 pixels wide and 200 
		 * pixels high.
		 * 
		 * The largest possible area for all charts except maps is 300,000 pixels. 
		 * As the maximum height or width is 1000 pixels, examples of maximum sizes 
		 * are 1000x300, 300x1000, 600x500, 500x600, 800x375, and 375x800.
		 * 
		 * For maps, the maximum size is 440 pixels wide by 220 pixels high.
		 * 
		 * Pie charts are clipped (only partially visible) if the size specified 
		 * is too small. General size guidelines for pie charts are:
		 *  - a two-dimensional chart needs to be roughly twice as wide as it 
		 *    is high.
		 *  - a three-dimensional chart needs to be roughly two and a half 
		 *    times wider than it is high.
		 * 
		 */
		$this->addParameter('chs', 'chs=' . $width . 'x' . $height);	
	}
	
	public function setChartData($data, Croese_Google_Chart_Encoding $encoding)
	{
		$value = $encoding->encode($data);
		$this->addParameter('chd', $value); // value heeft eventueel nog andere parameters die er achteraan zijn geplakt
	}
	
	public function setChartType($type)
	{
		$this->addParameter('cht', 'cht=' .  $type);
	}
	
	/**
	 * Zet de kleur(en) van een grafiek
	 * 
	 * Specify a color for each data point within a single data series by 
	 * separating chco color parameters with the pipe character (|) .
	 *
	 * @param string|array $colors
	 * @param string $sep
	 */
	// @todo $sep moet een boolean gaan worden, die standaard op false staat
	// er zijn toch maar 2 mogelijkheden
	public function setChartColors($colors, $sep = ',')
	{
		// validatie
		// @todo controleer of de kleuren echt in rrggbb formaat zijn
		/*
		if($sep != ',' || $sep != '|')
		{
			throw new Exception("De separator mag alleen ',' of '|' zijn");
			$sep = ',';
		}
		*/
		
		if(is_array($colors) && !empty($colors))
		{
			$value = implode($sep, $colors);
		}
		else
		{
			$value = $colors;
		}
		$this->addParameter('chco', 'chco=' . $value);
	}
	
	/*
	public function setSolidFill()
	{
		$this->addParameter('chf', 'chf=' . $value);
	}
	*/
	
	/**
	 * Met deze functie kan de titel van een grafiek gezet worden
	 * Optioneel kunnen ook de kleur en de grootte van de titel worden
	 * gezet.
	 * 
	 * Gebruik '|' om een nieuwe regel af te dwingen. newline karakters worden
	 * automatisch hiernaar toe overgezet
	 *
	 * @param String $title
	 * @param String $color
	 * @param int $fontsize
	 */
	public function setChartTitle($title, $color = null, $fontsize = null)
	{
		$this->_title = $title;
		
		$title = str_replace(' ', '+', $title);
		$title = str_replace("\n", '|', $title);
		$this->addParameter('chtt', 'chtt=' . $title);
		
		if(null != $color && null != $fontsize)
		{
			$this->setChartTitleColorSize($color, $fontsize);	
		}
		
	}
	
	public function setChartTitleColorSize($color, $fontsize)
	{
		// @todo validatie?
		$this->addParameter('chts', 'chts=' . $color . ',' . $fontsize);	
	}
	
	/**
	 * Multiple axis labels
	 */
	const X_BOTTOM = 'x';
	const X_TOP = 't';
	const Y_LEFT = 'y';
	const Y_RIGHT = 'r';
	
	public function setAxisType($axis)
	{
		// @todovalidatie, de volgende zijn alleen mogelijk: x, t, y, r
		$this->addParameter('chxt', 'chxt=' . implode(',', $axis));	
	}
	
	public function setAxisLabels($labels)
	{
		// @todo data validatie
		$i = 0;
		$values = array();
		foreach ($labels as $waarden)
		{
			$values[] = $i . ':|' . implode('|', $waarden);
			$i++;
		}
		$this->addParameter('chxl', 'chxl=' . implode('|', $values));	
	}
	
	/**
	 * Ik weet niet helemaal zeker wat deze functie nu precies voor effect heeft
	 * 
	 * input:
	 * array(
	 *   array('index' => , 'values' => array(1, 4, 7, 9),
	 *   array('index' => , 'values' => array(...),
	 *   ...
	 *   array('index' => , 'values' => array(...),
	 * );
	 * 
	 * output:
	 *  chxp=
	 * <axis index>,<label 1 position>,<label n position>|
	 * ...
	 * <axis index>,<label 1 position>,<label n position>
	 */
	public function setAxisLabelPositions($labelPositions)
	{
		$resultValues = array();
		foreach ($labelPositions as $labelPosition)
		{
			$values = array_merge(array($labelPosition['index']), $labelPosition['values']);
			$resultValues[] = implode(',', $values);  	
		}
		$this->addParameter(' chxp', ' chxp=' . implode('|', $resultValues));	
	}
	
	/**
	 * NIET GETEST
	 * 
	 * Zet de range van de assen
	 * 
	 * input:
	 * array(
	 *		array(index, start, end),
	 * 		array(index, start, end),
	 * 		...
	 * 		array(index, start, end),
	 * );
	 * 
	 * output:
	 *  chxr=
	 * <axis index>,<start of range>,<end of range>|
	 * ...
	 * <axis index>,<start of range>,<end of range>
	 *
	 * @param array $axisRange
	 */
	public function setAxisRange($axisRange)
	{
		$values = array();
		foreach($axisRange as $range)
		{
			$values[] = $range[0] . ',' . $range[1] . ',' . $range[2];	
		}
		$this->addParameter('chxr', 'chxr=' . implode('|', $values));	
	}
	
	/**
	 * 
	 * input:
	 * array(
	 * 		array(index, color, size, alignment),
	 * 		...
	 * 		array(index, color, size, alignment), 
	 * );
	 * 
	 * output:
	 * chxs=
	 * <axis index>,<color>,<font size>,<alignment>|
	 * ...
	 * <axis index>,<color>,<font size>,<alignment>
	 *
	 */
	public function setAxisStyles($axisStyles)
	{
		$values = array();
		foreach($axisStyles as $axeStyle)
		{
			$values[] = $axeStyle[0] . ',' . $axeStyle[1] . ',' . $axeStyle[2] . ',' . $axeStyle[3];	
		}
		$this->addParameter('chxr', 'chxr=' . implode('|', $values));	
	}
	
	/**
	 * For bar charts, specify bar thickness and spacing
	 * 
	 * space between bars defaults to 4 pixels, and the space between 
	 * groups defaults to 8 pixels.
	 *
	 * @param int $barWidth			bar width in pixels
	 * @param int $spaceBarsGgroup	optional space between bars in a group
	 * @param int $spaceGroups		optional space between groups
	 */
	public function setBarWidthSpacing($barWidth, $spaceBarsGgroup = 4, $spaceGroups = 8)
	{
		$this->addParameter('chbh', "chbh=$barWidth,$spaceBarsGgroup,$spaceGroups");		
	}
	
	/**
	 * -Chart colors-
	 * Solid fill
	 * Data scaling
	 * Linear gradient
	 * Linear stripes
	 * -Chart title-
	 * Chart legend
	 * -Multiple axis labels-
	 * Grid lines
	 * Shape markers
	 * Horizontal range markers
	 * Vertical range markers
	 * Line styles
	 * Fill area
	 * -Bar width and spacing-
	 * Bar chart zero line
	 * Pie chart and Google-o-meter labels
	 */
	
	
}